﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Kaleta.Network;

namespace StarWarsGame
{
    class TieFighter : IEnemy
    {

        private Player currentPlayer;
        private Vector3 lastPosition;
        private double lastEnemyBulletTime = 0;
        public bool InFov;
        

        public TieFighter(Game game, Vector3 pos, Quaternion rotation, float moveSpeed, float rotationSpeed, StarWarsGame.Game.DirectionMovement directionMovement, Model enemyModel)
        {
            Game = game;
            Position = pos;     
            Rotation = rotation;
            MoveSpeed = moveSpeed;
            RotationSpeed = rotationSpeed;
            DirMovement = directionMovement;
            EnemyModel = enemyModel;                        
        }

        public void UpdatePosition(GameTime gameTime, List<Player> players)
        {
            if (players.Count > 0)
            {
                GameLogic logic = new GameLogic();

                float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

                currentPlayer = players[0];
                foreach (Player player in players)
                {
                    if (Vector3.DistanceSquared(Position, player.Position) < Vector3.DistanceSquared(Position, currentPlayer.Position))
                    {
                        currentPlayer = player;
                    }
                }

                Vector3 facingDirection = Position;// -lastPosition;

                if (logic.CheckIfInView(Position, facingDirection, currentPlayer.Position, 75.0f, 45.0f))
                {
                    InFov = true;

                    Vector3 directionVector = Vector3.Normalize(currentPlayer.Position - Position);
                    Vector3 newUp = Math.Abs(Vector3.Dot(directionVector, Vector3.Up)) != 1
                                  ? Vector3.Up
                                  : Vector3.Cross(Vector3.Forward, directionVector);

                    Matrix lookAt = Matrix.CreateWorld(Position, directionVector, newUp);

                    Rotation = Quaternion.CreateFromRotationMatrix(lookAt);



                    float enemyMoveSpeed = (gameTime.ElapsedGameTime.Milliseconds / 500.0f * (logic.GameSpeed)) * MoveSpeed;
                    lastPosition = Position;
                    MoveForward(ref _position, Rotation, enemyMoveSpeed);
                }
                //just wander around
                else
                {
                    InFov = false;
                    Vector3 LookPosition = new Vector3(Position.X, Position.Y, Position.Z);
                    if (DirMovement == StarWarsGame.Game.DirectionMovement.Forward)
                    {
                        LookPosition = new Vector3(Position.X, Position.Y, Position.Z - 1000);
                    }
                    if (DirMovement == StarWarsGame.Game.DirectionMovement.BackWards)
                    {
                        LookPosition = new Vector3(Position.X, Position.Y, Position.Z + 1000);
                    }
                    if (DirMovement == StarWarsGame.Game.DirectionMovement.Left)
                    {
                        LookPosition = new Vector3(Position.X - 1000, Position.Y, Position.Z);
                    }
                    if (DirMovement == StarWarsGame.Game.DirectionMovement.Right)
                    {
                        LookPosition = new Vector3(Position.X + 1000, Position.Y, Position.Z);
                    }


                    Vector3 directionVector = Vector3.Normalize(LookPosition - Position);
                    Vector3 newUp = Math.Abs(Vector3.Dot(directionVector, Vector3.Up)) != 1
                                  ? Vector3.Up
                                  : Vector3.Cross(Vector3.Forward, directionVector);

                    Matrix lookAt = Matrix.CreateWorld(LookPosition, directionVector, newUp);

                    Rotation = Quaternion.CreateFromRotationMatrix(lookAt);


                    float leftRightRot = 0;

                    float turningSpeed = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
                    turningSpeed *= RotationSpeed * logic.GameSpeed;

                    Random random = new Random();
                    int randowVal = random.Next(0, 5);
                    if (randowVal == 0)
                        leftRightRot += turningSpeed;
                    if (randowVal == 1)
                        leftRightRot -= turningSpeed;

                    float upDownRot = 0;
                    Random randomHeight = new Random();
                    int randomHeightVal = randomHeight.Next(0, 5);
                    if (randomHeightVal == 0)
                        upDownRot += turningSpeed;
                    if (randomHeightVal == 1)
                        upDownRot -= turningSpeed;

                    Quaternion additionalRot = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, -1), leftRightRot) * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), upDownRot);
                    Rotation *= additionalRot;
                    float enemyMoveSpeed = (gameTime.ElapsedGameTime.Milliseconds / 500.0f * (logic.GameSpeed)) * MoveSpeed;
                    lastPosition = Position;
                    MoveForward(ref _position, Rotation, enemyMoveSpeed);
                }
            }
        }

        public void Fire(GameTime gameTime)
        {
            if (currentPlayer != null)
            {
                if (InFov)
                {
                    Random random_number = new Random();
                    float speed = (float)random_number.Next(30) / 100f;
                    double currentTime = gameTime.TotalGameTime.TotalMilliseconds;
                    if (currentTime - lastEnemyBulletTime > 750)
                    {
                        Bullet newBullet = new Bullet(true);
                        newBullet.bulletPosition = Position;
                        newBullet.bulletRotation = Rotation;

                        Game.enemyBulletList.Add(newBullet);

                        lastEnemyBulletTime = currentTime;

                        speed += .08f;
                        //Game.Laserbolts.setup_and_fire(Position, currentXwing.Position, Game.randcolors.gimmie(), speed, true);//, Matrix.CreateTranslation(localXwing.Position));
                    }
                }

            }
        }

        public void MoveForward(ref Vector3 position, Quaternion rotationQuat, float speed)
        {
            //Default forward
            Vector3 dirVector = new Vector3(0, 0, -1);

            if (!InFov)
            {

                //if (DirMovement == StarWarsGame.Game.DirectionMovement.BackWards)
                //{
                //    dirVector = new Vector3(0, 0, 1);
                //}
                //if (DirMovement == StarWarsGame.Game.DirectionMovement.Left)
                //{
                //    dirVector = new Vector3(1, 0, 0);
                //}
                //if (DirMovement == StarWarsGame.Game.DirectionMovement.Right)
                //{
                //    dirVector = new Vector3(-1, 0, 0);
                //}
            }

            Vector3 addVector = Vector3.Transform(dirVector, rotationQuat);
            position += addVector * speed;
        }


        public void Draw(Matrix[] enemyModelTransforms)
        {

            Game.device.SamplerStates[0].AddressU = TextureAddressMode.Clamp;
            Game.device.SamplerStates[0].AddressV = TextureAddressMode.Clamp;

            EnemyModel.CopyAbsoluteBoneTransformsTo(enemyModelTransforms);

            Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(Rotation) * Matrix.CreateTranslation(Position);


            foreach (ModelMesh mesh in EnemyModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    Matrix worldM = enemyModelTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.World = worldM;
                    effect.Projection = Game.projectionMatrix;
                    effect.View = Game.viewMatrix;
                }

                mesh.Draw();
            }
        }

        #region private properties

        private float _moveSpeed;
        private float _rotationSpeed;
        private Quaternion _rotation;
        private Vector3 _position;
        private Game _game;
        private Model _enemyModel;
        private StarWarsGame.Game.DirectionMovement _dirMovement;


        #endregion

      
        public Game Game
        {
            get { return _game; }
            set { _game = value; }
        }

        public float MoveSpeed
        {
            get { return _moveSpeed; }
            set { _moveSpeed = value; }
        }

        public float RotationSpeed
        {
            get { return _rotationSpeed; }
            set { _rotationSpeed = value; }
        }


        public Quaternion Rotation
        {
            get { return _rotation; }
            set { _rotation = value; }
        }

        public Vector3 Position
        {
            get { return _position; }
            set { _position = value; }
        }

        public Model EnemyModel
        {
            get { return _enemyModel; }
            set { _enemyModel = value; }
        }

        private StarWarsGame.Game.DirectionMovement DirMovement
        {
            get { return _dirMovement; }
            set { _dirMovement = value; }
        }

    }
}
